/*
  Copyright (C) 2013 Napspirit / Thierry Rochelet

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


package com.napspirit.tmx.ui;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;

import com.napspirit.tmx.data.TMXTU;


public class ListPanel extends JPanel
    implements ListSelectionListener , DocumentListener , ActionListener {

    private Frame parent;

    private JScrollPane listScroller;
    private JPanel listPanel;

    private DefaultListModel listModel;
    private JList itemList;
    private TMXTUCellRenderer cellRenderer;


    private JPanel filterPanel;
    
    // Filter on TUID
    private JTextField filter_tuid;
    private JButton filter_tuid_clear;

    // Filter on category
    private JComboBox filter_category;

    // Filter on references
    private JComboBox filter_references;
    private static final String [] filter_references_content = new String [] { "" , "Used" , "Not used" };

    // Filter on defined locale
    private JComboBox filter_defined_locale;

    // Filter on not defined locale
    private JComboBox filter_not_defined_locale;


    private boolean loading = true;

    public ListPanel(Frame parent) {
        this.parent = parent;
        this.cellRenderer = new TMXTUCellRenderer();
        this.listModel = new DefaultListModel();
        this.loading = true;
        this.prepare();
        this.loading = false;
    }


    // ============ TUID =============

    // Prepare the panel with the filter on TUID
    private void prepare_filter_tuid () {
        this.filterPanel.add(new JLabel("TUID"));

        this.filter_tuid = new JTextField();
        this.filter_tuid.setText("");
        this.filter_tuid.setEditable(true);
        this.filter_tuid.getDocument().addDocumentListener(this);
        this.filterPanel.add(this.filter_tuid);

        this.filter_tuid_clear = new JButton("Clear");
        this.filter_tuid_clear.addActionListener(this);
        this.filterPanel.add(this.filter_tuid_clear);
    }



    // ============== FILTER REFERENCES ==============

    // Prepare the panel to filter on references
    private void prepare_filter_references () {
        this.filterPanel.add(new JLabel("References"));

        this.filter_references = new JComboBox(ListPanel.filter_references_content);
        this.filter_references.addActionListener(this);
        this.filterPanel.add(this.filter_references);

        this.filter_references.setSelectedIndex(0);

        this.filterPanel.add(new JLabel(""));
    }


    // ============== FILTER CATEGORY ==============

    // Prepare the panel to filter on category
    private void prepare_filter_category () {
        this.filterPanel.add(new JLabel("Category"));

        this.filter_category = new JComboBox();
        this.filter_category.addActionListener(this);
        this.filterPanel.add(this.filter_category);

        this.filterPanel.add(new JLabel(""));
    }

    private void populate_filter_category () {
        String selected = (String)this.filter_category.getSelectedItem();
        this.filter_category.removeAllItems();
        this.filter_category.addItem("*"); // no filter
        this.filter_category.addItem(""); // filter on not cateogry
        this.filter_category.setSelectedIndex(0);

        Enumeration<String> categories = this.parent.getTMX().getCategories();
        while (categories.hasMoreElements()) {
            String cat = categories.nextElement();
            this.filter_category.addItem(cat);
            if (selected!=null) {
                if (cat.compareTo(selected)==0) {
                    this.filter_category.setSelectedItem(cat);
                }
            }
        }

        this.filter_category.updateUI();
    }



    // ============== FILTER DEFINED LOCALE ==============

    // Prepare the panel to filter on defined locale
    private void prepare_filter_defined_locale () {
        this.filterPanel.add(new JLabel("Defined locale"));

        this.filter_defined_locale = new JComboBox();
        this.filter_defined_locale.addActionListener(this);
        this.filterPanel.add(this.filter_defined_locale);

        this.filterPanel.add(new JLabel(""));
    }

    private void populate_filter_defined_locale () {
        String selected = (String)this.filter_defined_locale.getSelectedItem();
        this.filter_defined_locale.removeAllItems();
        this.filter_defined_locale.addItem(""); // no filter
        this.filter_defined_locale.setSelectedIndex(0);

        String [] langs = this.parent.getTMX().getDefinedLocales();
        for (String lang : langs) {
            this.filter_defined_locale.addItem(lang);
            if (selected!=null) {
                if (lang.compareTo(selected)==0) {
                    this.filter_defined_locale.setSelectedItem(lang);
                }
            }
        }

        this.filter_defined_locale.updateUI();
    }




    // ============== FILTER NOT DEFINED LOCALE ==============

    // Prepare the panel to filter on not_defined locale
    private void prepare_filter_not_defined_locale () {
        this.filterPanel.add(new JLabel("Not defined locale"));

        this.filter_not_defined_locale = new JComboBox();
        this.filter_not_defined_locale.addActionListener(this);
        this.filterPanel.add(this.filter_not_defined_locale);

        this.filterPanel.add(new JLabel(""));
    }
    
    private void populate_filter_not_defined_locale () {
        String selected = (String)this.filter_not_defined_locale.getSelectedItem();
        this.filter_not_defined_locale.removeAllItems();
        this.filter_not_defined_locale.addItem(""); // no filter
        this.filter_not_defined_locale.setSelectedIndex(0);

        String [] langs = this.parent.getTMX().getDefinedLocales();
        for (String lang : langs) {
            this.filter_not_defined_locale.addItem(lang);
            if (selected!=null) {
                if (lang.compareTo(selected)==0) {
                    this.filter_not_defined_locale.setSelectedItem(lang);
                }
            }
        }

        this.filter_not_defined_locale.updateUI();
    }





    // =========== UI Prepare =======

    private void prepare() {
        this.removeAll();
        this.setLayout(new BorderLayout());

        // Filter
        this.filterPanel = new JPanel();
        TitledBorder title_filter = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "Filter/Search");
        this.filterPanel.setBorder(title_filter);
        this.filterPanel.setLayout(new GridLayout(5,3));

        this.prepare_filter_tuid();
        this.prepare_filter_category();
        this.prepare_filter_defined_locale();
        this.prepare_filter_not_defined_locale();
        this.prepare_filter_references();
        this.add(this.filterPanel, BorderLayout.NORTH);

        // List of data
        this.listPanel = new JPanel();
        TitledBorder title_list = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "Translation Unit : tuid");
        this.listPanel.setBorder(title_list);
        this.listPanel.setLayout(new BorderLayout());

        // Item list
        this.itemList = new JList();
        this.itemList.setCellRenderer(cellRenderer);
        this.itemList.addListSelectionListener(this);
        this.itemList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        this.itemList.setVisibleRowCount(-1);
        this.itemList.setModel(listModel);

        this.listScroller = new JScrollPane(itemList);
        this.listScroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.listScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        this.listPanel.add(this.listScroller,BorderLayout.CENTER);


        this.add(this.listPanel, BorderLayout.CENTER);
    }

    // ======= Main list =====

    private void populate_list () {
        String tuid = this.filter_tuid.getText().trim();
        String category = (String)this.filter_category.getSelectedItem();
        String defined_locale = (String)this.filter_defined_locale.getSelectedItem();
        String not_defined_locale = (String)this.filter_not_defined_locale.getSelectedItem();
        String references = (String)this.filter_references.getSelectedItem();

        this.listModel.removeAllElements();

        Enumeration<TMXTU> tus = this.parent.getTMX().getTUs();
        while (tus.hasMoreElements()) {
            TMXTU tu = tus.nextElement();
            boolean add = true;

            // Filtering ....
            if (add && defined_locale!=null)
                if (!defined_locale.isEmpty())
                    if (!tu.isLocaleDefined(new Locale(defined_locale)))
                        add = false;
            
            if (add && not_defined_locale!=null)
                if (!not_defined_locale.isEmpty()) 
                    if (tu.isLocaleDefined(new Locale(not_defined_locale)))
                        add = false;

            if (add && tuid!=null)
                if (!tuid.isEmpty())
                    if (!tu.getID().contains(tuid))
                        add = false;

            if (add && references!=null) {
                if (!references.isEmpty()) {
                    if (references.compareTo(ListPanel.filter_references_content[1])==0) {
                        // USED
                        if (!tu.hasReferences()) {
                            add = false;
                        }
                    }
                    else if (references.compareTo(ListPanel.filter_references_content[2])==0) {
                        // NOT USED
                        if (tu.hasReferences()) {
                            add = false;
                        }
                    }
                }
            }


            if (add && category!=null) {
                if (category.compareTo("*")==0) {
                    // nothing todo !
                }
                else if (tu.getCategory().compareTo(category)!=0) {
                    add = false;
                }
            }
            
            
            // Add or not ?
            if (add)
                this.listModel.addElement(tu);
        }

    }

    public void valueChanged(ListSelectionEvent event) {

        if ( (event.getSource() == itemList) && itemList.getSelectedIndex() > -1) {
            TMXTU selected = (TMXTU)listModel.get(itemList.getSelectedIndex());
            if (selected==this.parent.getTMX().getCurrent()) {
                return; // similar... nothing todo !!
            }

            if (this.parent.confirmChangeCurrent()) {
                this.parent.getTMX().setCurrent( (TMXTU)listModel.get(itemList.getSelectedIndex()));
                this.parent.refreshEntry();
            }
            else {
                this.itemList.setSelectedValue(this.parent.getTMX().getCurrent(),true);
            }
        }
        else if ( (event.getSource() == itemList) && itemList.getSelectedIndex() == 0) {
            if (this.parent.confirmChangeCurrent()) {
                this.parent.getTMX().setCurrent( (TMXTU)null);
            }
            else {
                this.itemList.setSelectedValue(this.parent.getTMX().getCurrent(),true);
            }
        }
    }


    // Refresh the man UI panel
    public void refresh() {
        this.loading = true;

        this.populate_list();
        this.populate_filter_category();
        this.populate_filter_defined_locale();
        this.populate_filter_not_defined_locale();

        if (this.parent.getTMX().getCurrent()!=null) {
            this.itemList.setSelectedValue(this.parent.getTMX().getCurrent(),true);
        }

        this.loading = false;
        this.parent.pack();
        this.repaint();
    }


    // Fitler
    public void actionPerformed(ActionEvent event) {
        if (this.loading) {
            return;
        }

        if (event.getSource() == this.filter_tuid_clear) {
            this.filter_tuid.setText("");
        }
        this.refresh();
    }


    public void changedUpdate(DocumentEvent e) { this.refresh(); }
    public void insertUpdate(DocumentEvent e) { this.refresh(); }
    public void removeUpdate(DocumentEvent e) { this.refresh(); }

}


